package com.devunion.bogdan.model.project.dao;

import com.devunion.bogdan.model.project.*;
import com.devunion.bogdan.persistence.BaseDaoObject;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.*;


/**
 * <p>Hibernate implementation of <code>UserDao</code></p>
 *
 * @author Viktar Liaskovich
 */
public class HibernatePaperDao extends BaseDaoObject<Paper> implements PaperDao {

    /**
     * {@inheritDoc}
     */
    public Paper getByKey(Serializable key) {
        return (Paper) hibernateTemplate.get(Paper.class, key);
    }

    /**
     * {@inheritDoc}
     */
    public List<Paper> loadAll() {
        return hibernateTemplate.loadAll(Paper.class);
    }

    public Project getPorject(final Long paperId) {
        return (Project) hibernateTemplate.execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException {
                final List list = session.createQuery("select p from Project p inner join p.entries paper where paper.id = :paperId").
                        setParameter("paperId", paperId, Hibernate.LONG).
                        list();

                return list == null || list.size() == 0 ? null : list.get(0);
            }
        });
    }

    public List<Paper> search(final String name, final String type) {
        return (List<Paper>) hibernateTemplate.execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException, SQLException {

                if ("ANY".equals(type)) {
                    Query query = session.createQuery("from Paper p where lower(p.info.title) like :name ");
                    query.setParameter("name", "%" + name.toLowerCase() + "%");
                    return query.list();
                }

                return session.createQuery("from Paper p where lower(p.info.title) like :name and p.info.type = :type")
                        .setParameter("type", PaperType.valueOf(type))
                        .setParameter("name", "%" + name.toLowerCase() + "%")
                        .list();
            }
        });
    }
}